package com.petiot.rabbitmq;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeoutException;

import javax.net.ssl.SSLContext;

import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

import com.petiot.rabbitmq.PushService.PushMsgCallback;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.ShutdownSignalException;
import com.rabbitmq.tools.json.JSONUtil;

public class WavIoTClient {
			    

	
	private String mGroupId;
	private String mClientUid;
	private static String mClientQueueName;
	private static List<WavIoTDevice> mDeviceList = new ArrayList<WavIoTDevice>();
	private static final int SESSION_TIMER = 60;//one minute
    private Connection mConnection;
	public static Channel mChannel;
	private String mConsumerTag=null;
	private static final String EXCHANGE_NAME = "petiot.direct";

	private static final String TAG = "WavIoTClient";
	
	public WavIoTClient(String groupId,String clientUid)
	{
		mGroupId = groupId;
		mClientUid = clientUid;	
	}        

	
	public void addNewDevice(String deviceUid,String id,String pwd, PushMsgCallback callBack)
	{		
		WavIoTDevice one = new WavIoTDevice(mGroupId,deviceUid,id,pwd,mClientQueueName, callBack);
		mDeviceList.add(one);	
	}
	
	public Channel getChannel()
	{
		return mChannel;
	}
	
	public Connection getConnection()
	{
		return mConnection;
	}
	
	public String getClientQueueName()
	{
		return mClientQueueName;
	}
	
	public String getClientUid()
	{
		return mClientUid;
	}
	
	
	public List<WavIoTDevice> getDevices()
	{
		return mDeviceList;
	}
	
	
	public boolean initAmqpSessionSsl(String host,int port,String amqpId,String amqpPwd,String vhost)
	{
		try {
			//SSLContext sslversion = SSLContext.getInstance("TLSv1.2");
			//sslversion.init(null, null, null);
			ConnectionFactory factory = new ConnectionFactory();
			factory.setHost(host);
			factory.setPort(port);
			factory.setPassword(amqpPwd);
			factory.setUsername(amqpId);
			factory.useSslProtocol();
			factory.setVirtualHost(vhost);
			
			mConnection = factory.newConnection();
			mChannel = mConnection.createChannel();
			mClientQueueName = mChannel.queueDeclare().getQueue();
			mChannel.queueBind(mClientQueueName, EXCHANGE_NAME,mClientQueueName);
			mConsumerTag = mChannel.basicConsume(mClientQueueName, true, OnMessageHandler);
			Log.d(TAG,"queueName: " + mClientQueueName);
			Log.d(TAG, "login comsumerTag: " + mConsumerTag);
			Log.e(TAG, "0000 channel = " + mChannel);
			
			return true;
			
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return false;
	}
	
	public void cancelConsumer() throws IOException
	{
		if(mConsumerTag != null)
		{
			mChannel.basicCancel(mConsumerTag);
		}
	}
	
	public void quit() throws IOException
	{
		mConnection.close();
	}
	
	private Consumer OnMessageHandler = new Consumer(){

		@Override
		public void handleCancel(String arg0) throws IOException {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void handleCancelOk(String arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void handleConsumeOk(String arg0) {
			// TODO Auto-generated method stub
			
		}

		

		@Override
		public void handleDelivery(java.lang.String consumerTag,Envelope envelope,AMQP.BasicProperties properties,
                byte[] body) throws IOException {
			// TODO Auto-generated method stub
			//鎺ユ敹鍒版秷鎭箣鍚庯紝鍦ㄨ繖閲屽鐞�
			String message = new String(body, "UTF-8");
			System.out.println(" [cccccccccccc] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
			
			Log.e(TAG, "cccccccc  message = " + message);
			
			try {
				//String response = new String(body,Constants.EncodedCharst);
				JSONObject jsonMsg = new JSONObject(message);
			
				if(!jsonMsg.getString("waviot").equals("1.0"))
				{
					Log.e(TAG, "Invalid waviot version : " + jsonMsg.getString("waviot"));
					return;
				}
				JSONObject header = jsonMsg.getJSONObject("header");
				JSONObject jsonBody = jsonMsg.optJSONObject("body");
				/**
				String hashCode = JSONUtil.reqLoginHMACMD5_HashCode(Constants.HMAC_MD5_KEY, JSONUtil.getValueFromOrderedJson(jsonBody));
				
				hashCode = JSONUtil.dealStr(hashCode);
				if(!hashCode.equals(header.getString("hashcode")))
				{
					Log.e(TAG, "Invalid hash code ");
					Log.d(TAG, "hashCode:" + hashCode+"; body:" + jsonBody.toString()+"; server hashCode:" + header.getString("hashcode"));
					
					return;
				}
				**/
				
				if(header.has("deviceID"))
				{
					boolean foundDevice = false;
				    for(WavIoTDevice one : mDeviceList)
				    {
				    	if(one.isDeviceMsg(jsonMsg))
				    	{
				    		foundDevice = true;
				    		one.msgHandler(mChannel,consumerTag, envelope, properties, jsonMsg);
				    		Log.e(TAG, "5555 mChannel = " + mChannel);
				    		break;
				    	}
				    }
					
				    if(!foundDevice)
				    {
				    	Log.e(TAG, "No matched Target Device : " + header.getString("deviceID"));
				    }
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		}

		@Override
		public void handleRecoverOk(String arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void handleShutdownSignal(String arg0,
				ShutdownSignalException arg1) {
			// TODO Auto-generated method stub
			
		}
		
		
	};
	


}
